/***************************************************************************
 *           minrem_imageproc - Image processing for Minority Remote
 *
 *  Fri Apr 23 08:10:56 2010
 *  Copyright  2010  Christophe Seyve
 *  Email cseyve@free.fr
 ****************************************************************************/

/*
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
#ifndef MINREM_IMAGEPROC_H
#define MINREM_IMAGEPROC_H

// OpenCV
#include <cv.h>
#include <cv.hpp>

#include <stdint.h>

typedef uint8_t u8;
typedef uint32_t u32;

/** @brief 2D vector */
typedef struct {
	float x, y;
} t_vect;
#define MAX_SPEED_HISTO	4

/** @brief Magnetic fly */
typedef struct {
	int ID;
	u8 active;	/*! Activation flag */
	int history; /*! Number of active iterations */

	u8 major;	/*! Flag for main mouvement (for diaply maily) */
	u8 dead;	/*! Disappearance counter */
	int ponder; /*! Current iteration position ponderation total */
	float x, y;	/*! position in m_motionSensorImage */
	float old_x, old_y;	/*! previous position in m_motionSensorImage */
	t_vect speed_histo[MAX_SPEED_HISTO];
} t_fly;




/** @brief Image processing for Minority remote

*/
class MinRemImageProc {
public:
	/** @brief Default constructor */
	MinRemImageProc();
	/** @brief Default destructor */
	~MinRemImageProc();

	/** @brief Process an image */
	int processImage(IplImage *);

	IplImage * getDebugImage() { return m_debugImage; };
	IplImage * getDiffImage() { return m_diffImage; };
	IplImage * getGrownImage() { return m_grownImage; };
	IplImage * getMotionSensorImage() { return m_motionSensorImage; };

	int getMovement(float * dx, float *dy);

	/// Get sound volume
	int getVolume() { return m_volume; };

	/// Get play/pause
	bool isPlay() { return m_play; };

	/// Get graph of motion history
	IplImage * getMotionHistoImage() { return m_motionHistoImage; };
private:
	/** @brief Initialize all internal variables and buffers */
	void init();
	/** @brief Purge all internal variables and buffers */
	void purge();

	bool m_play;

	/// Volume from 0 to 100
	int m_volume;

	/// History of input images
	IplImage **m_imageHisto;

	/// Image of motion history
	IplImage *m_motionHistoImage;

	float speed_x, speed_y;
	float pos_x, pos_y;
	/// Previous position in history image
	int old_hx, old_hy;
	/// History
	int m_history;

	/// Tracking with elementary fly algorithm
	void processFliesTracking();

	t_fly * m_flies;
	int m_nb_flies;



	/// Image for debug display
	IplImage * m_debugImage;

	/// Image for difference image
	IplImage * m_diffImage;
	/// Image for region growing (blobs)
	IplImage * m_grownImage;

	/// Motion sensor like image, with downscaled binary
	IplImage * m_motionSensorImage;

	/** @brief Grow regions */
	int growRegions();

// FLIES ANIMATION
	/// Returns true if there is a fly at this position
	bool isThereAFly(int x, int y);
	/** @brief get the fly active at this position
		 Returns NULL if there is no fly at this position
		 */
	t_fly *whichFly(int x, int y);
	/** @brief Create and reset a fly at this position

		@return NULL if there is no more space */
	t_fly *createFly(int x, int y);

	/** @brief Update fly with new position and ponderation factor */
	void updateFly(t_fly * pfly, int x, int y, u8 ponder);

	/** @brief Clear flies updated flag */
	void clearFliesIteration();

	/** @brief Draw a fly in m_debugImage */
	void drawFly(t_fly * pfly);

};

#endif // MINREM_IMAGEPROC_H

// End of file

